//
// Created by Administrator on 2018/11/1 0001.
//



#include <jni.h>
#include <GLES3/gl3.h>

#include <android/log.h>
#include <stdlib.h>

#define LOG_TAG "CPP_RENDER"

#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)

#ifdef __cplusplus
extern "C" {
#endif


const char vertexShaderSource[] =
        "#version 310 es\n"
                "layout(location = 0) in vec4 vPosition;"
                "layout(location = 1) in vec2 aTextureCoordinate;"
                "out vec2 vTextCoord;"
                "void main(){"
                "    gl_Position = vPosition;"
                "    vTextCoord = aTextureCoordinate;"
                "}\0";

const char fragmentShaderSource[] =
        "#version 310 es\n"
                "precision mediump float;"
                "out vec4 fragColor;"
                "in vec2 vTextCoord;"
                "uniform sampler2D s_texture;"
                "void main(){"
                "fragColor = texture(s_texture,vTextCoord);"
                "}\0";


const GLubyte pixels[4 * 3] = {
        255,0,0,
        0,255,0,
        0,0,255,
        255,255,0
};

const GLfloat vertexArray[] = {
        -0.5f,0.5f,0.0f,
        -0.5f,-0.5f,0.0f,
        0.5f,0.5f,0.0f,
        0.5f,-0.5f,0.0f

};

const GLfloat sCood[] = {
        0.0f, 0.0f,
        0.0f, 1.0f,
        1.0f, 0.0f,
        1.0f, 1.0f
};

bool checkGLError(const char* funcName){
    GLint err = glGetError();
    if(err != GL_NO_ERROR){
        LOGI("GL error after %s():0x%08x\n",funcName,err);
        return true;
    }
    return false;
}




GLuint createShader(GLenum shaderType,const char*src){
    GLuint shader = glCreateShader(shaderType);
    if(!shader){
        checkGLError("glGreateShader");
        return 0;
    }
    LOGI("create shader");
    glShaderSource(shader,1,&src,NULL);
    GLint compiled = GL_FALSE;
    glCompileShader(shader);

    glGetShaderiv(shader,GL_COMPILE_STATUS,&compiled);
    if(compiled == 0){
        GLint infoLogLen = 0 ;
        glGetShaderiv(shader,GL_INFO_LOG_LENGTH,&infoLogLen);
        if(infoLogLen > 0){
            GLchar *infoLog = (GLchar *) malloc(infoLogLen);
            glGetShaderInfoLog(shader,infoLogLen,NULL,infoLog);
            LOGI("Cound not compile %s shader:\n"
                         "%s\n",
                         shaderType == GL_VERTEX_SHADER?"vertex":"fragment",
                        infoLog);
            free(infoLog);
        }
        glDeleteShader(shader);
        return 0;
    }
    return shader;
}


GLuint createProgram(const char* vtxSrc,const char* fragSrc){
    GLuint vtxShader = 0 ;
    GLuint fragShader = 0;
    GLuint program = 0 ;
    GLint linked = GL_FALSE;

    vtxShader = createShader(GL_VERTEX_SHADER,vtxSrc);
    LOGI("create fragment shader");
    fragShader = createShader(GL_FRAGMENT_SHADER,fragSrc);
    program = glCreateProgram();


    glAttachShader(program,vtxShader);
    glAttachShader(program,fragShader);

    glLinkProgram(program);
    return program;

}


GLuint program;

GLuint textureId;

GLint texturePosition;

JNIEXPORT void JNICALL
Java_com_cloudream_glndk_Render_renderCreate(JNIEnv *env, jobject obj) {
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    program = createProgram(vertexShaderSource,fragmentShaderSource);
    if(!program){
        LOGI("create program failed!");
    }

    texturePosition = glGetAttribLocation(program,"s_texture");

    glPixelStorei(GL_UNPACK_ALIGNMENT,1);

    glGenTextures(1,&textureId);

    glBindTexture(GL_TEXTURE_2D,textureId);
    glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,2,2,0,GL_RGB,GL_UNSIGNED_BYTE,pixels);

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);

}


JNIEXPORT void JNICALL
Java_com_cloudream_glndk_Render_renderChagen(JNIEnv *env, jobject obj, jint width, jint height) {
    LOGI(" render change ");
    glViewport(0, 0, width, height);
}


JNIEXPORT void JNICALL
Java_com_cloudream_glndk_Render_drawFrame(JNIEnv *env, jobject obj) {
    glClear(GL_COLOR_BUFFER_BIT);

    glUseProgram(program);
    glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,vertexArray);
    glEnableVertexAttribArray(0);



    glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,0,sCood);
    glEnableVertexAttribArray(1);

    glActiveTexture(textureId);
    glBindTexture(GL_TEXTURE_2D,textureId);


    glUniform1i(texturePosition,0);


    //绘制单个三角形
    //glDrawArrays(GL_TRIANGLES,0,3);
    //绘制三角带
    glDrawArrays(GL_TRIANGLE_STRIP,0,4);






    glDisableVertexAttribArray(0);
}


#ifdef __cplusplus
}
#endif